// ptuserio.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iocommon.h"
#include <windows.h>
#include <iostream>
using namespace std;

void sayHello()
{
    cout<<"Welcome to 'passThruivi' driver ioctl interface!"<<endl;
}

void sayGoodBye()
{
    cout<<"'passthruivi' ioctl interface ended."<<endl;
    cout<<"For more information, please contact the author at 'wentaoshang@gmail.com'."<<endl;
}

void printUsage()
{
    cout<<endl;
    cout<<"ioctl command usage: "<<endl<<endl;
    cout<<"  To set Mod,                      input 1 and input Mod value when asked"<<endl;
    cout<<"  To get Mod,                      input 2"<<endl;
    cout<<"  To set Res,                      input 3 and input Res value when asked"<<endl;
    cout<<"  To get Res,                      input 4"<<endl;
    cout<<"  To set TimeOut,                  input 5 and input TimeOut value (in seconds) when asked"<<endl;
    cout<<"  To get TimeOut,                  input 6"<<endl;
    cout<<"  To enable Mod/Res Autoconfig,    input 7"<<endl;
    cout<<"  To disable Mod/Res Autoconfig,   input 8"<<endl;
    cout<<"  To exit,                         input 0"<<endl<<endl;
    cout<<"For more information, please contact the author at 'wentaoshang@gmail.com'."<<endl<<endl;;
    cout<<"Now input command : ";
}

int _tmain(int argc, _TCHAR* argv[])
{
    sayHello();

    HANDLE PtHandle = CreateFile(
      "\\\\.\\PassThru",
      GENERIC_READ | GENERIC_WRITE,
      0,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      NULL 
      );

    if( PtHandle == INVALID_HANDLE_VALUE ) {
        cout<<"Failed to open 'PassThru' device! Install it first!"<<endl;
        return -1;
    }

    DWORD byteReturned;

    int cmd = 0;
    USHORT temp = 0;
    LARGE_INTEGER time;
    BOOL ret = 0;

    printUsage();
    cin>>cmd;
    cout<<endl;

    while( cmd != 0 ) {

        switch(cmd) {
            case 1:
                cout<<"Input Mod value ( <= 4096 ) : ";
                cin>>temp;
                cout<<endl;

                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_SET_MOD, &temp, sizeof(temp), NULL, 0, &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Set Mod failed! Should be smaller than 4096 or the Res value!"<<endl;
                else
                    cout<<"ioctl : Set Mod to : "<<temp<<endl;
                break;

            case 2:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_GET_MOD, NULL, 0, &temp, sizeof(temp), &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Get Mod failed!"<<endl;
                else
                    cout<<"ioctl : Current Mod is : "<<temp<<endl;
                break;

            case 3:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_GET_MOD, NULL, 0, &temp, sizeof(temp), &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Get Mod failed!"<<endl;

                cout<<"Input Res value ( < "<<temp<<" ) : ";
                cin>>temp;
                cout<<endl;

                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_SET_RES, &temp, sizeof(temp), NULL, 0, &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Set Res failed!"<<endl;
                else
                    cout<<"ioctl : Set Res to : "<<temp<<endl;
                break;

            case 4:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_GET_RES, NULL, 0, &temp, sizeof(temp), &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Get Res failed!"<<endl;
                else
                    cout<<"ioctl : Current Res is : "<<temp<<endl;
                break;

            case 5:
                cout<<"Input TimeOut value (in seconds) : ";
                cin>>time.QuadPart;
                cout<<endl;

                time.QuadPart = time.QuadPart * 10000000;

                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_SET_TIMEOUT, &time, sizeof(time), NULL, 0, &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Set TimeOut failed!"<<endl;
                else
                    cout<<"ioctl : Set TimeOut to : "<<( time.QuadPart / 1E7 )<<" s."<<endl;
                break;

            case 6:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_GET_TIMEOUT, NULL, 0, &time, sizeof(time), &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Get TimeOut failed!"<<endl;
                else
                    cout<<"ioctl : Current TimeOut is : "<<( time.QuadPart / 1E7 )<<" s."<<endl;
                break;

            case 7:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_SET_AUTOCONFIG, NULL, 0, NULL, 0, &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Set AutoConfig failed!"<<endl;
                else
                    cout<<"ioctl : AutoConfig enabled."<<endl;
                break;

            case 8:
                ret = DeviceIoControl( PtHandle, IOCTL_PTUSERIO_UNSET_AUTOCONFIG, NULL, 0, NULL, 0, &byteReturned, NULL );
                if( ret == 0 )
                    cout<<"ioctl : Unset AutoConfig failed!"<<endl;
                else
                    cout<<"ioctl : AutoConfig disabled."<<endl;
                break;

            default:
                cout<<"ioctl : Operation not supported!"<<endl;
        }

        ret = 0;
        printUsage();
        cin>>cmd;
        cout<<endl;
    }

    CloseHandle( PtHandle );

    sayGoodBye();

    return 0;
}
